package com.ruoyi.common.utils.wxpay;

import com.ruoyi.common.utils.wxpay.utils.PayCommonUtil;
import com.ruoyi.common.utils.wxpay.utils.WxConfigUtil;
import com.ruoyi.common.utils.wxpay.utils.XMLUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.JDOMException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * Description:微信支付接口
 * Author:THP
 * Date:2019/04/23 15:58
 */
@Slf4j
@UtilityClass
public class WXPay {

    /**
     * 微信支付
     * @param price 总金额
     * @param body  商品描述
     * @param notifyUrl 回调地址
     * @param outTradeNo 订单号
     * @return R
     */
    public static Map<String, Map> wxPrePay(String price, String body, String notifyUrl,String outTradeNo ,HttpServletRequest request) {
        Map<String, Map> resultMap = new HashMap<String, Map>();
        Map<String, Object> flag = new TreeMap<>();
        SortedMap<Object, Object> parameters = new TreeMap<>();
        //调用创建统一下单签名
//        if("true".equals(PayCommonUtil.createUnifiedSign(price,body,notifyUrl,outTradeNo,request).get("flag"))) {*/
            parameters = PayCommonUtil.createUnifiedSign(price, body, notifyUrl,outTradeNo, request);
//        }
        //封装请求参数结束
        String requestXML = PayCommonUtil.getRequestXml(parameters);
        //调用统一下单接口
        String result = PayCommonUtil.httpsRequest(WxConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
        System.out.println("\n" + result);
        try {
            /**统一下单接口返回正常的prepay_id，再按签名规范重新生成签名后，将数据传输给APP。参与签名的字段名为appId，partnerId，prepayId，nonceStr，timeStamp，package。注意：package的值格式为Sign=WXPay**/
            Map<String, String> map = XMLUtil.doXMLParse(result);
            SortedMap<Object, Object> parameterMap2 = new TreeMap<Object, Object>();
            parameterMap2.put("appid", WxConfigUtil.APPID);
            parameterMap2.put("partnerid", WxConfigUtil.MCH_ID);
            parameterMap2.put("prepayid", map.get("prepay_id"));
            parameterMap2.put("package", "Sign=WXPay");
            parameterMap2.put("noncestr", PayCommonUtil.createNoncestr());
            //本来生成的时间戳是13位，但是ios必须是10位，所以截取了一下
            parameterMap2.put("timestamp", Long.parseLong(String.valueOf(System.currentTimeMillis()).toString().substring(0, 10)));
            String sign2 = PayCommonUtil.createSign("UTF-8", parameterMap2);
            parameterMap2.put("sign", sign2);
            parameterMap2.put("out_trade_no",outTradeNo);
            flag.put("flag", true);
            resultMap.put("flag", flag);
            resultMap.put("wxPay", parameterMap2);
            return resultMap;
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultMap;
    }

    /**
     * 微信回调数据解析
     * @return R
     */
    public static Map<String, String> wxNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
        //读取参数
        boolean flag = false;
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());
        for (Object keyValue : m.keySet()) {
            System.out.println(keyValue + "=" + m.get(keyValue));
        }
        return m;
    }
    /**
     * 微信回调返回给微信的数据
     * @return R
     */
    public static boolean wxNotify(Map<String,String> m, HttpServletRequest request,HttpServletResponse response) throws IOException, JDOMException {
        boolean flag = true;
        //过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        //判断签名是否正确
        String resXml = "";
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams)) {
            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                     resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                             + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                     log.info("订单已处理");
                     flag = true;
                     return flag;
            }
         }
//        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams)) {
//            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
//                // 这里是支付成功
//                //商户号
//                String mchId = (String) packageParams.get("mch_id");
//                //用户标识
//                String openId = (String) packageParams.get("openid");
//                //商户订单号
//                String outTradeNo = (String) packageParams.get("out_trade_no");
//                String totalFee = (String) packageParams.get("total_fee");
//                //微信支付订单
//                String transactionId = (String) packageParams.get("transaction_id");
//                if (!WxConfigUtil.MCH_ID.equals(mchId) ||  new BigDecimal(totalFee).compareTo(new BigDecimal(price).multiply(new BigDecimal(100))) != 0) {
//                    log.info("支付失败,错误信息：" + "参数错误");
//                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                            + "<return_msg><![CDATA[参数错误]]></return_msg>" + "</xml> ";
//                } else {
//                    if ("0".equals(payStatus)) {
//                        //支付的价格
//                        //订单状态的修改。根据实际业务逻辑执行
//                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
//                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//                        flag = true;
//                        return flag;
//
//                    } else {
//                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
//                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//                        log.info("订单已处理");
//                        flag = true;
//                        return flag;
//                    }
//                }
//            } else {
//                log.info("支付失败,错误信息：" + packageParams.get("err_code"));
//                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
//                return flag;
//            }
//
//
//        } else {
//            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                    + "<return_msg><![CDATA[通知签名验证失败]]></return_msg>" + "</xml> ";
//            log.info("通知签名验证失败");
//            return flag;
//        }
        //------------------------------
        //处理业务完毕
        //------------------------------
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return flag;
    }


//    /**
//     * 微信退款
//     * @param rdfund
//     * @param req
//     * @return
//     * @throws Exception
//     */
//    public static Map<String, Object>  refundUtil(RefundModel rdfund, HttpServletRequest req,Integer type) throws Exception{
//        Map<String, Object> map = new HashMap<String, Object>();
//        int price100 = new BigDecimal(rdfund.getRefund_fee()).multiply(new BigDecimal(100)).intValue();
//        if (price100 <= 0) {
//            log.error("微信退款失败》》"+"错误码:"+map.get("return_msg")+"  ;"
//                    + "描述:"+map.get("err_code_des"));
//            return map;
//        }

//        Map<String, Object> mp = new HashMap<String, Object>();
//        //设置支付账户信息
//        String MchKey = ""; //商户号秘钥
//        String MchId = ""; //商户号id
//        rdfund.setAppid(BasicInfo.APP_AppID);
//        rdfund.setMch_id(BasicInfo.APP_MchId);
//        MchKey = BasicInfo.APP_MchKey;
//        MchId = BasicInfo.APP_MchId;
//
//
//        rdfund.setNonce_str(PayUtil.getRandomStr());
//        rdfund.setSign_type("MD5");
//        rdfund.setSign(SignUtil.sign(SignUtil.createRefundSign(rdfund),MchKey));
//
//        try{
//            XMLUtil xmlUtil= new XMLUtil();
//            xmlUtil.xstream().alias("xml", rdfund.getClass());
//
//            String xml = xmlUtil.xstream().toXML(rdfund);
//            String response = PayUtil.ssl(BasicInfo.refundurl, xml,req,MchId);
//            System.out.println(response);
//            Map<String, String> map = xmlUtil.parseXml(response);
//            if("SUCCESS".equals(map.get("result_code"))){
//                mp.put("stu", true);
//                return mp;
//            }else{
//                mp.put("stu", false);
//                mp.put("errMsg", map.get("return_msg"));
//                mp.put("errDes", map.get("err_code_des"));
//                log.error("微信退款失败》》"+"错误码:"+map.get("return_msg")+"  ;"
//                        + "描述:"+map.get("err_code_des"));
//                return mp;
//            }
//        }catch (Exception e) {
//            log.error("微信退款异常》》"+e);
////            throw new MyException(SystemError.WX_RETREIEV_ERROR.getCode(),
////                    SystemError.WX_RETREIEV_ERROR.getMessage());
////        }
//        return map;
//    }

}


